home *** CD-ROM | disk | FTP | other *** search
GW-BASIC | 1986-02-19 | 4.7 KB | 156 lines |
- 90 REM -------------- A S O R T / M E R G E P R O G R A M -------------
- 91 REM
- 92 REM Original written by Terry Dettmann, Assoc. Ed of 80 MICRO magazine.
- 93 REM Modifed & adapted to IBM PC by Gerry L. Kilgore
- 94 REM
- 95 REM --------Define all variables to be integers
- 96 REM
- 100 DEFINT A-Z
- 101 SCREEN 0,0:COLOR 7,0:CLS:PRINT TAB(35) "SORT/MERGE":PRINT:PRINT
- 102 LINE INPUT "Enter record length to be sorted ==> ";A$
- 103 NR=VAL(A$):IF NR<4 OR NR>254 THEN 102 ELSE NL=8000/NR
- 105 REM
- 106 REM-----Variables NL, NFL & NX control size of SORT/MERGE
- 107 REM-----NL=Max No. of lines in memory; NFL=Max No. file buffers available
- 108 REM-----NX=Max No. of temporary files to use
- 109 REM
- 110 NFL=8: NX=16
- 114 REM
- 115 REM-------LN$() is the line buffer array
- 116 REM-------FF$() is the temporary filename list
- 117 REM-------FC$() is the set of files to use to merge
- 118 REM
- 120 DIM LN$(NL),FF$(NX),FC$(NFL)
- 125 REM-------FT$ is the temporary filename root
- 126 REM-------FT is the number of the current temporary file
- 130 FT$="Temp": FT=0
- 135 REM------FNCTR$(X$) prints X$ centered on an 80 character line
- 136 REM------FNHDR$(X$) prints a 3 line header
- 140 DEF FNCTR$(X$)=STRING$((80-LEN(X$))/2,32)+X$
- 150 DEF FNHDR$(X$)=STRING$(80,220)+FNCTR$(X$)+CHR$(13)+STRING$(80,220)
- 195 REM
- 196 REM - - - - - - - SORT/MERGE DEMO: MAIN PROGRAM - - - - - - - - -
- 197 REM
- 198 REM----------Get the input and output file names (can be the same)
- 199 REM
- 200 LINE INPUT "Input file ==> ";FI$: LINE INPUT "Output file ==> ";FO$
- 233 PRINT:PRINT "Enter drive number for the sort work files (A,B,C) ==> ";
- 235 Z$=INKEY$:IF Z$="" OR Z$=CHR$(13) THEN 235
- 236 IF Z$="A" OR Z$="a" OR Z$="B" OR Z$="b" OR Z$="C" OR Z$="c" THEN 240 ELSE PRINT Z$:Z$=":"+Z$
- 240 PRINT:PRINT
- 245 REM----------Get the input file
- 250 OPEN "I",1,FI$
- 255 REM----------Read in part of the input file
- 260 GOSUB 1000
- 265 REM-----------Sort it
- 270 GOSUB 2000
- 275 REM----------Write it to a temporary file
- 280 GOSUB 3000
- 285 REM----------If all the data from the input file not read then get more
- 290 IF FLG<>1 THEN 260
- 295 REM----------Close all files
- 300 CLOSE
- 305 REM----------Start the merge operation
- 310 GOSUB 4000
- 315 REM----------Open the files - 1 for output
- 316 REM - 2-NZ for input
- 320 OPEN "O",1,FC$(1):PRINT
- 330 PRINT FNCTR$("OUTPUT FILE: "+FC$(1))
- 340 FOR I=2 TO NZ
- 350 OPEN "I",I,FC$(I)
- 360 PRINT FNCTR$("INPUT FILE: "+FC$(I))
- 365 REM-----------Get the first line from each file
- 370 LINE INPUT #I,LN$(I)
- 380 NEXT I:PRINT
- 385 REM-----------Choose the smallest line
- 390 GOSUB 5000
- 395 REM-----------If there is no smallest line then we're done this pass
- 400 IF LN$="" THEN 430
- 405 REM-----------Put the smalles line to the output file
- 410 PRINT #1,LN$:K=K+1':PRINT USING "####> ";K;:PRINT LN$
- 420 GOTO 390
- 430 CLOSE:PRINT
- 434 REM----------Kill old temporary input files
- 435 FOR I=2 TO NZ:KILL FC$(I):PRINT FNCTR$("KILLING FILE: "+FC$(I)):NEXT I:PRINT
- 440 PRINT:IF FC$(1)<>FO$ THEN EF=1 ELSE EF=0
- 445 REM---------If we're not done, then go get the rest
- 450 IF EF=1 THEN 310
- 460 END
- 995 REM
- 996 REM - - - - - - - Read from input file - - - - - - - -
- 997 REM
- 998 REM FLG is a flag to mark the end of the input file
- 999 REM
- 1000 FLG=0
- 1020 PRINT:PRINT FNCTR$("READING FROM: "+FI$)
- 1025 REM-------Read in up to nl lines
- 1030 FOR I=1 TO NL
- 1040 IF EOF(1) THEN FLG=1: GOTO 1070
- 1050 LINE INPUT #1,LN$(I):'PRINT USING "####> ";I;:PRINT LN$(I)
- 1060 NEXT I
- 1065 IF EOF(1) THEN FLG=1
- 1067 REM--------NM is the no. of lines actually read in
- 1070 NM=I-1: RETURN
- 1995 REM
- 1996 REM - - - - - - - - Sort data in memory - - - - - - - - - -
- 1997 REM
- 1998 REM-----------Set the initial gap
- 1999 REM
- 2000 GAP=NM
- 2015 REM----------If gap gets down to 1, we're done
- 2020 IF GAP <= 1 THEN RETURN
- 2025 REM----------Look at 1/2 the previous gap
- 2030 GAP = INT(GAP/2)
- 2035 REM----------Set the swap flag to no swaps made
- 2040 FG = 0
- 2050 FOR I=1 TO NM-GAP
- 2060 IF LN$(I) > LN$(I+GAP) THEN SWAP LN$(I),LN$(I+GAP):FG=1
- 2070 NEXT I
- 2080 IF FG=1 THEN 2040 ELSE 2020
- 2995 REM
- 2996 REM - - - - - - Write data to temporay output file - - - - - - -
- 2997 REM
- 2998 REM---------FT is the current temporary output file
- 2999 REM---------Make NF$ the current temporary file name & save it
- 3000 FT=FT+1: NF$=FT$+MID$(STR$(FT),2)+Z$: FF$(FT)=NF$: IF FT>=NX THEN FLG=1
- 3015 REM---------Write the lines to the temporary file
- 3020 OPEN "O",2,NF$: PRINT
- 3030 PRINT FNCTR$("TEMPORARY FILE: "+NF$)
- 3040 FOR I=1 TO NM:PRINT#2,LN$(I)':PRINT USING "####> ";I;:PRINT LN$(I)
- 3045 NEXT I:PRINT
- 3050 CLOSE 2
- 3060 RETURN
- 3993 REM
- 3994 REM - - - - - - - Pick output file & input offset
- 3995 REM
- 3996 REM-----------F1 is 1st file read, F2 is last file read
- 3997 REM-----------FF is no. of the intermediate merge file
- 3998 REM
- 4000 F1=F2+1: F2=F2+NFL-1: FF=(FF+1) MOD 2
- 4020 FF$=FT$+"X"+MID$(STR$(FF),2)+Z$
- 4030 IF FC$(1)="" THEN 4060
- 4040 FC$(2)=FC$(1): F2=F2-1: J=2
- 4050 GOTO 4070
- 4060 J=1
- 4070 IF F2>FT THEN F2=FT
- 4080 IF F2=FT THEN FC$(1)=FO$ ELSE FC$(1)=FF$
- 4090 FOR I=F1 TO F2: J=J+1
- 4100 FC$(J)=FF$(I)
- 4110 NEXT I
- 4120 NZ=J: K=0
- 4130 RETURN
- 4995 REM
- 4996 REM - - - - - - - - Select smallest input line - - - - - - - - - -
- 4997 REM
- 5000 FOR I=2 TO NZ: IF LN$(I)<>"" THEN 5050
- 5020 NEXT I
- 5030 LN$=""
- 5040 RETURN
- 5050 FC=I: LN$=LN$(I): J=I+1
- 5060 IF J>NZ THEN 5100
- 5070 FOR I=J TO NZ: IF LN$(I)="" THEN 5090
- 5080 IF LN$>LN$(I) THEN LN$=LN$(I): FC=I
- 5090 NEXT I
- 5100 IF NOT EOF(FC) THEN LINE INPUT #FC,LN$(FC) ELSE LN$(FC)=""
- 5110 RETURN
-